package cn.edu.tju.wallet.service;

import cn.edu.tju.core.model.User;
import cn.edu.tju.core.security.repository.UserRepository;
import cn.edu.tju.wallet.domain.RechargeRule;
import cn.edu.tju.wallet.domain.Transaction;
import cn.edu.tju.wallet.domain.VirtualWallet;
import cn.edu.tju.wallet.dto.VipLevelDTO;
import cn.edu.tju.wallet.repository.RechargeRuleRepository;
import cn.edu.tju.wallet.repository.TransactionRepository;
import cn.edu.tju.wallet.repository.VirtualWalletRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 充值服务类
 */
@Service
public class RechargeService {

    @Autowired
    private VirtualWalletRepository walletRepository;

    @Autowired
    private RechargeRuleRepository rechargeRuleRepository;

    @Autowired
    private TransactionRepository transactionRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private VipLevelService vipLevelService;

    /**
     * 充值功能
     *
     * @param userId 用户ID
     * @param amount 充值金额
     * @return 充值结果
     */
    @Transactional(rollbackFor = Exception.class)
    public VirtualWallet.DepositResult recharge(Long userId, BigDecimal amount) {
        // 1. 参数校验
        if (userId == null || userId <= 0) {
            throw new IllegalArgumentException("用户ID不合法");
        }
        if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new IllegalArgumentException("充值金额必须大于0");
        }
        if (amount.compareTo(new BigDecimal("100000")) > 0) {
            throw new IllegalArgumentException("单次充值金额不能超过100000元");
        }

        // 2. 查询钱包
        Optional<VirtualWallet> walletOptional = walletRepository.findByUserId(userId);
        if (walletOptional.isEmpty()) {
            // 如果钱包不存在，自动创建
            VirtualWallet newWallet = new VirtualWallet(userId);
            newWallet.setDeleted(false);
            newWallet.setCreateTime(LocalDateTime.now());
            walletRepository.save(newWallet);
        }

        VirtualWallet wallet = walletRepository.findByUserId(userId).orElseThrow();

        // 3. 查询充值规则
        List<RechargeRule> rules;
        try {
            rules = rechargeRuleRepository.findByStatusOrderByPriorityDesc(RechargeRule.RuleStatus.ACTIVE);
        } catch (Exception e) {
            // 如果查询充值规则失败，使用无奖励规则
            rules = List.of();
        }

        RechargeRule rule = null;
        if (!rules.isEmpty()) {
            for (RechargeRule r : rules) {
                if (r.getStartTime() != null && r.getStartTime().isAfter(LocalDateTime.now())) {
                    continue; // 规则还未开始
                }
                if (r.getEndTime() != null && r.getEndTime().isBefore(LocalDateTime.now())) {
                    continue; // 规则已过期
                }
                if (r.getMinAmount() != null && amount.compareTo(r.getMinAmount()) < 0) {
                    continue; // 金额不满足最小要求
                }
                rule = r;
                break;
            }
        }

        // 4. 执行充值
        VirtualWallet.DepositResult result = wallet.deposit(amount, rule);

        // 5. 保存钱包
        walletRepository.save(wallet);

        // 6. 记录交易流水
        BigDecimal balanceBefore = wallet.getBalance().subtract(amount).subtract(result.getBonus());
        Transaction transaction = new Transaction(
            wallet.getId(),
            Transaction.TransactionType.RECHARGE,
            amount,
            balanceBefore,
            wallet.getBalance()
        );
        transaction.setRemark("用户充值: " + amount + "元");
        if (rule != null && result.getBonus().compareTo(BigDecimal.ZERO) > 0) {
            transaction.setRemark("用户充值: " + amount + "元，奖励: " + result.getBonus() + "元");
        }
        transaction.setDeleted(false);
        transaction.setCreateTime(LocalDateTime.now());
        transaction.setUpdateTime(LocalDateTime.now());
        transactionRepository.save(transaction);

        // VIP升级检查：充值增加
        updateUserVipLevelAfterRecharge(userId, amount);

        return result;
    }

    /**
     * 充值成功后更新用户VIP等级
     * @param userId 用户ID
     * @param amount 充值金额
     */
    private void updateUserVipLevelAfterRecharge(Long userId, BigDecimal amount) {
        try {
            // 重新从数据库查询最新用户数据
            User user = userRepository.findById(userId).orElse(null);
            if (user == null) return;

            // 增加累计充值金额
            user.addRecharge(amount);

            // 保存用户信息（包含新增的充值金额）
            user = userRepository.save(user);

            // 检查VIP升级
            VipLevelDTO newLevel = vipLevelService.upgradeUserVipLevel(user);

            // 保存升级后的用户信息
            user = userRepository.save(user);

            if (newLevel != null) {
                System.out.println(String.format(
                    "用户 %s 充值后VIP升级成功: %s (等级%d)",
                    user.getUsername(), newLevel.getName(), newLevel.getLevel()
                ));
            }
        } catch (Exception e) {
            // 记录日志但不中断流程
            System.err.println("VIP升级失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
}